package com.gupao.strategyAndTemplate.proxyLogger;

import com.gupao.strategyAndTemplate.abstractLogger.LoggerFactory;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Description: //TODO:JDK动态代理的日志工厂，提供一个调用日志的接口
 * @ClassName: ProxyLoggerFactory
 * @Author: msx
 * @CreateDate: 2018/3/23 18:46
 */
public class JDKProxyLoggerFactory  implements InvocationHandler{


    //被代理的对象，把引用给保存下来
    private ILoggerFactory target;

    /**
     * 代理类执行的地方
     * @param target
     * @return
     */
    public Object executeLogger(ILoggerFactory target){
        this.target = target;
        Class<?> clazz = target.getClass();

        //下半截，老师深入底层来给大家讲解字节码是如何重组的
        //用来生成一个新的对象（字节码重组来实现）
        //类加载器：加载重新字节码重组的类，接口，重新的$proxy0的类需要实现该接口，并实现类，
        // 所以这个this必须要实现接口，这是jdk的规定,否则无法生成这个类，
        return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
    }

    /**
     * 重写InvocationHandler的方法
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     * 这个类会在$proxy0中实现的，public class $proxy0 extends Proxy implements InvocationHandler{}
     * 所以：当调用的时候，会走userActionLogger这个方法，然后在这里面invoke
     * public Object userActionLogger(){
     *     this.h.invoke();//h:是InvocationHandler中的对象,意思就是调用下面的这段invoke代码
     * }
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //这个method就是对象传过来的调用方法，rags是参数，比如：userLoginLogger
        method.invoke(this.target,args);
         return null;
    }
}
